package com.aismy.admin.service.impl;

import com.aismy.admin.dto.ScaleSubmitDTO;
import com.aismy.admin.dto.ScaleResultDTO;
import com.aismy.admin.entity.*;
import com.aismy.admin.exception.BusinessException;
import com.aismy.admin.mapper.EvalScaleMapper;
import com.aismy.admin.mapper.QuestionMapper;
import com.aismy.admin.mapper.QuestionOptionMapper;
import com.aismy.admin.service.*;

import com.aismy.admin.utils.SecurityUtils;
import com.aismy.admin.vo.OptionVO;
import com.aismy.admin.vo.QuestionVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import io.micrometer.common.util.StringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Aismy
 * @date 2025/03/08
 **/
@Service
@RequiredArgsConstructor
public class EvalScaleServiceImpl extends ServiceImpl<EvalScaleMapper, EvalScale> implements EvalScaleService {

    private final QuestionMapper questionMapper;
    private final QuestionOptionMapper optionMapper;
    private final EvalRecordService recordService;

    @Override
    public List<EvalScale> getAllScales() {
        return this.list(
                new LambdaQueryWrapper<EvalScale>()
                        .eq(EvalScale::getStatus, 1)  // 只获取启用的量表
                        .orderByDesc(EvalScale::getCreatedAt)
        );
    }

    @Override
    public EvalScale getScaleDetail(Long scaleId) {
        EvalScale scale = this.getById(scaleId);
        if (scale == null || scale.getStatus() != 1) {
            throw new RuntimeException("量表不存在或未启用");
        }

        // 获取量表的所有题目
        List<Question> questions = questionMapper.selectList(
                new LambdaQueryWrapper<Question>()
                        .eq(Question::getScaleId, scaleId)
                        .orderByAsc(Question::getSort)
        );

        // 获取所有题目的选项
        if (!questions.isEmpty()) {
            for (Question question : questions) {
                if (!"TEXT".equals(question.getType())) {
                    List<QuestionOption> options = optionMapper.selectList(
                            new LambdaQueryWrapper<QuestionOption>()
                                    .eq(QuestionOption::getQuestionId, question.getId())
                                    .orderByAsc(QuestionOption::getSort)
                    );
                    question.setOptions(options);
                }
            }
        }

        scale.setQuestions(questions);
        return scale;
    }

    @Override
    public Page<EvalScale> getScalePage(Integer page, Integer size, String query) {
        return this.page(
                new Page<>(page, size),
                new LambdaQueryWrapper<EvalScale>()
                        .like(StringUtils.isNotBlank(query), EvalScale::getName, query)
                        .orderByDesc(EvalScale::getCreatedAt)
        );
    }

    @Override
    @Transactional
    public Long submitEvaluation(Long scaleId, ScaleSubmitDTO submitDTO) {
        // 1. 获取当前用户
        Long userId = SecurityUtils.getUserId();

        // 2. 获取量表信息
        EvalScale scale = this.getById(scaleId);
        if (scale == null) {
            throw new RuntimeException("量表不存在");
        }

        // 3. 计算总分
        int totalScore = 0;
        Map<Long,Question> questionMap = new HashMap<>();
        for (ScaleSubmitDTO.AnswerDTO answerDTO : submitDTO.getAnswers()) {
            Question question = questionMapper.selectById(answerDTO.getQuestionId());
            if (question == null) continue;
            questionMap.put(answerDTO.getQuestionId(), question);
            // 根据题目类型计算分数
            if ("TEXT".equals(question.getType())) {
                totalScore += question.getScore(); // 文本题按题目分值计算
            } else {
                // 选择题按选项分值计算
                List<QuestionOption> options = optionMapper.selectList(
                        new LambdaQueryWrapper<QuestionOption>()
                                .in(QuestionOption::getId, answerDTO.getAnswer())
                );
                totalScore += options.stream().mapToInt(QuestionOption::getScore).sum();
            }
        }

        // 4. 评估等级和生成结论
        String level = evaluateLevel(totalScore, scale.getTotalScore());
        String evaluation = generateEvaluation(level, totalScore, scale.getTotalScore());

        // 5. 保存测评记录
        EvalRecord record = new EvalRecord();
        record.setUserId(userId);
        record.setScaleId(scaleId);
        record.setTotalScore(totalScore);
        record.setLevel(level);
        record.setEvaluation(evaluation);
        // 生成提交数据
        record.setSubmitData(buildSubmitData(submitDTO.getAnswers(),questionMap));
        recordService.save(record);
        return record.getId();
    }

    public String buildSubmitData(List<ScaleSubmitDTO.AnswerDTO> answers, Map<Long, Question> questionMap) {
        StringBuilder sb = new StringBuilder();
        for (ScaleSubmitDTO.AnswerDTO answerDTO : answers) {
            sb.append("Question: ").append(questionMap.get(answerDTO.getQuestionId()).getContent()).append("\n");
            sb.append("Answer: ").append(answerDTO.getContent()).append("\n");
            sb.append("--------------------------------------------------\n");
        }
        return sb.toString();
    }

    @Override
    public ScaleResultDTO getEvaluationResult(Long recordId) {
        EvalRecord record = recordService.getById(recordId);

        if (record == null) {
            throw new RuntimeException("未找到测评记录");
        }

        // 2. 构建结果
        ScaleResultDTO result = new ScaleResultDTO();
        result.setTotalScore(record.getTotalScore());
        result.setLevel(record.getLevel());
        result.setEvaluation(record.getEvaluation());
        result.setSuggestions(generateSuggestions(record.getLevel()));

        return result;
    }

    @Override
    public ScaleResultDTO generateReport(Long scaleId) {
        return getEvaluationResult(scaleId);
    }

    // 评估等级
    private String evaluateLevel(int score, int totalScore) {
        double percentage = (double) score / totalScore;
        if (percentage >= 0.8) return "SEVERE";
        if (percentage >= 0.6) return "MODERATE";
        if (percentage >= 0.4) return "MILD";
        return "NORMAL";
    }

    // 生成评估结论
    private String generateEvaluation(String level, int score, int totalScore) {
        String template = "本次测评得分为%d分（总分%d分），处于%s水平。";
        String levelDesc;
        switch (level) {
            case "SEVERE":
                levelDesc = "严重";
                break;
            case "MODERATE":
                levelDesc = "中度";
                break;
            case "MILD":
                levelDesc = "轻度";
                break;
            default:
                levelDesc = "正常";
                break;
        }
        return String.format(template, score, totalScore, levelDesc);
    }

    // 生成建议
    private List<String> generateSuggestions(String level) {
        List<String> suggestions = new ArrayList<>();
        switch (level) {
            case "SEVERE":
                suggestions.add("建议及时寻求专业心理咨询师的帮助");
                suggestions.add("保持规律的作息时间，适当运动");
                suggestions.add("与家人朋友多交流，获取社会支持");
                break;
            case "MODERATE":
                suggestions.add("建议考虑寻求心理咨询师的帮助");
                suggestions.add("学习简单的减压方法，如深呼吸、冥想等");
                suggestions.add("保持积极的生活态度，培养兴趣爱好");
                break;
            case "MILD":
                suggestions.add("注意调节情绪，保持心态平和");
                suggestions.add("适当参加社交活动，增加与他人的互动");
                suggestions.add("培养良好的生活习惯");
                break;
            default:
                suggestions.add("继续保持良好的心理状态");
                suggestions.add("定期进行自我心理评估");
                suggestions.add("培养积极健康的生活方式");
        }
        return suggestions;
    }

    /**
     * 获取量表的所有题目及选项
     */
    @Override
    public List<QuestionVO> getScaleQuestions(Long scaleId) {
        // 获取量表的所有题目
        List<Question> questions = questionMapper.selectList(
                new LambdaQueryWrapper<Question>()
                        .eq(Question::getScaleId, scaleId)
                        .orderByAsc(Question::getSort)
        );

        if (questions.isEmpty()) {
            return new ArrayList<>();
        }

        // 获取所有题目的ID
        List<Long> questionIds = questions.stream()
                .map(Question::getId)
                .collect(Collectors.toList());

        // 一次性查询所有题目的选项
        List<QuestionOption> allOptions = optionMapper.selectList(
                new LambdaQueryWrapper<QuestionOption>()
                        .in(QuestionOption::getQuestionId, questionIds)
                        .orderByAsc(QuestionOption::getSort)
        );

        // 将选项按题目ID分组
        Map<Long, List<QuestionOption>> optionMap = allOptions.stream()
                .collect(Collectors.groupingBy(QuestionOption::getQuestionId));

        // 组装返回数据
        return questions.stream().map(question -> {
            QuestionVO vo = new QuestionVO();
            BeanUtils.copyProperties(question, vo);

            List<QuestionOption> options = optionMap.getOrDefault(question.getId(), new ArrayList<>());
            List<OptionVO> optionVOs = options.stream().map(option -> {
                OptionVO optionVO = new OptionVO();
                BeanUtils.copyProperties(option, optionVO);
                return optionVO;
            }).collect(Collectors.toList());

            vo.setOptions(optionVOs);
            return vo;
        }).collect(Collectors.toList());
    }

    @Override
    public void updateStatus(Long id, Integer status) {
        EvalScale scale = getById(id);
        if (scale == null) {
            throw new BusinessException("量表不存在");
        }
        if (status == 0) {
            scale.setStatus(0);
            updateById(scale);
        } else {
            // 启用量表时，检查题目是否完整
            Integer totalScore = scale.getTotalScore();
            List<Question> questions = questionMapper.selectList(new LambdaQueryWrapper<Question>().eq(Question::getScaleId, id));
            long count = questions.stream().mapToInt(Question::getScore).sum();
            if (count != totalScore) {
                throw new BusinessException("题目数量与总分不匹配，请检查题目是否完整");
            }
            scale.setStatus(1);
            updateById(scale);
        }
    }
}
